package old;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
//import java.util.Scanner;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class CommandInput {
	
	public static CommandInput staticInput;
	ArrayList<String> output = new ArrayList<String>();
	ArrayList<String> guiUpcomingList = new ArrayList<String>();
	ArrayList<Task> upcomingTenList = null;
	private ArrayList<Task> outputViewList = null;
	BasicFeaturesV1 basicFeaturesV1 = new BasicFeaturesV1();
	
	//constructor
	private CommandInput(){

	}
	
	public void parseCmd(String command) {
		String[] temp;
		//delimiter
				String delimiter = " ";
				//given string will be split by the argument delimiter provided.
				temp = command.split(delimiter);
				
				if(temp[0].equals("+") || temp[0].equals("+*"))
					AddTask(temp);
				else if(temp[0].equals("-"))
					RemoveTask(temp);
				else if(temp[0].equals("mod"))
					ModifyTask(temp);
					
				else if(temp[0].equals("view"))
					ViewTask(temp);
				else if(temp[0].equals("search"))
					//SearchTask(temp);
					;
				else if(temp[0].equals("done"))
					DoneTask(temp);
				else if(temp[0].equals("save"))
					//SaveALLTask(temp);
					;
				else
					output.add("Command error!");
				
				output.add("Complete."); //this is for testing
	}
	
    //pass Object with statements to be displayed to GUI
    public ArrayList<String> out(){
    	return output;
    }
    
    public ArrayList<Task> outTable(){
    	return outputViewList;
    }
    
    //print to console instead
    public void out2console(){
    	int size = output.size();
        
		 for(int i = 0; i < size ; i++){
			 //output.add(size);
			 String astr = output.get(i);
			 System.out.println(astr);
		 }
		 output.clear();
    }
	
	public void AddTask(String[] item)  { //starttime, duetime, date, label, taskdes, venue, importance
		
		boolean Importance = false;
		boolean TaskSetCorrect = true;
		int i=0,j=0,k=0;
		char[] temp;
		String TaskDescription="";
		String tempWord="";
		
		//Attributes to be stored from here on
		Task task;
		int dd=0,mm=0,yy=0;
		int StartTime=0,DueTime=0;
		String StoreVenue="";
		String StoreLabel="";
		String StoreTask="";
		String ddmmyy=""; //for XML
		String StartTimeString="0"; //for XML
		String DueTimeString="0"; //for XML
		//Ends here
		
		if(item[0].equals("+*")) {
			Importance = true;
		}

		for(j=0; j<item.length; j++) {
			temp = item[j].toCharArray();
			
			if(temp[0] == '@') {
				if(temp.length==5) {
					DueTime = StartTime(item[j]);
					DueTimeString = GetStartTime(temp);
					System.out.println("Due time only1 --> "+DueTimeString);
					if(CheckTime(DueTimeString))
						System.out.println("Due time only --> "+DueTimeString);
					else {
						System.out.println("Invalid Time");
						TaskSetCorrect = false;
					}
				}
				else if(temp.length==10) {
					StartTime = StartTime(item[j]);
					StartTimeString = GetStartTime(temp);
					DueTime = DueTime(item[j]);
					DueTimeString = GetDueTime(temp);
					if(CheckTime(DueTimeString) && CheckTime(StartTimeString))
						System.out.println("Due & Start time --> "+DueTimeString+" & "+StartTimeString);
					else {
						System.out.println("Invalid Time");
						TaskSetCorrect = false;
					}
				}
				else {
					System.out.println("Invalid Time");
					TaskSetCorrect = false;
				}
			}
			
			if(temp[0] == '#') {
				tempWord = CheckDate(temp);
				if(!tempWord.isEmpty()) {
					dd=ConvertDateDD(tempWord);
					mm=ConvertDateMM(tempWord);
					yy=ConvertDateYY(tempWord);
					ddmmyy = tempWord;
				}
				else {
					System.out.println("Invalid Date in CI");
					TaskSetCorrect = false;
				}
			}
			
			if(temp[0] == '$') {
				tempWord = GetWord(temp);
				StoreVenue = tempWord;
			}
			if(temp[0] == ':') {
				tempWord = GetWord(temp);
				StoreLabel = tempWord;
			}
			if(temp[0] == '*') {
				Importance = true;
			}
			if(temp[0]!='*' && temp[0]!='#' && temp[0]!='@' && temp[0]!='$' && temp[0]!='+' && temp[0]!=':') {
				TaskDescription = TaskDescription + item[j]+' ';
			}
		}
		
		//if Date is not set, assume today
		if(ddmmyy.isEmpty() && !DueTimeString.equals("0")) {
			Format formatter;
			Date date = new Date();
		    formatter = new SimpleDateFormat("ddMMyy");
		    String s = formatter.format(date);
		    ddmmyy = s;
		    System.out.println("Date not set, but got time, therefore set as TODAY= " + ddmmyy);
		    dd=ConvertDateDD(ddmmyy);
			mm=ConvertDateMM(ddmmyy);
			yy=ConvertDateYY(ddmmyy);
		}
		else if (!ddmmyy.isEmpty() && DueTimeString.equals("0")){
			System.out.println("Date Set and Time not set, if no other error, add task");
		}
		else
			System.out.println("Date and Time not set, if no other error, set task as forever type");
		
		if(TaskDescription.isEmpty()) {
			System.out.println("no Task des ERROR!");
			TaskSetCorrect = false;
		}
		else {
			StoreTask = TaskDescription;
		}
		
		System.out.println("From CmdInput: TaskSetCorrect");
		if(TaskSetCorrect) {
			Task newTask = new Task(dd, mm, yy, StartTimeString, DueTimeString, StoreLabel, Importance, StoreTask, StoreVenue);
			basicFeaturesV1.addTask(newTask);
			System.out.println("uhh"+dd+mm+yy+"uhhhh");
			basicFeaturesV1.printeverything();
		}
		else {
			output.add("No task stored");
			System.out.println("No task stored");	
		}
		
		outputViewList = basicFeaturesV1.retrieveUpcomingTask();
	}
	
public Task newTask(String[] item)  { //starttime, duetime, date, label, taskdes, venue, importance		
		boolean Importance = false;
		boolean TaskSetCorrect = true;
		int i=0,j=0,k=0;
		char[] temp;
		String TaskDescription="";
		String tempWord="";
		
		//Attributes to be stored from here on
		Task task;
		int dd=0,mm=0,yy=0;
		int StartTime=0,DueTime=0;
		String StoreVenue="";
		String StoreLabel="";
		String StoreTask="";
		String ddmmyy=""; //for XML
		String StartTimeString="0"; //for XML
		String DueTimeString="0"; //for XML
		//Ends here
		
		if(item[0].equals("+*")) {
			Importance = true;
		}
		
		for(int n =0; n<item.length; n++){
			System.out.println("itemhere: "+ n + " "+item[n]);
			
		}

		for(j=0; j<item.length; j++) {
			temp = item[j].toCharArray();
			System.out.println(item.length);
			if(temp[0] == '@') {
				if(temp.length==5) {
					DueTime = StartTime(item[j]);
					DueTimeString = GetStartTime(temp);
					System.out.println("Due time only1 --> "+DueTimeString);
					if(CheckTime(DueTimeString))
						System.out.println("Due time only --> "+DueTimeString);
					else {
						System.out.println("Invalid Time");
						TaskSetCorrect = false;
					}
				}
				else if(temp.length==10) {
					StartTime = StartTime(item[j]);
					StartTimeString = GetStartTime(temp);
					DueTime = DueTime(item[j]);
					DueTimeString = GetDueTime(temp);
					if(CheckTime(DueTimeString) && CheckTime(StartTimeString))
						System.out.println("Due & Start time --> "+DueTimeString+" & "+StartTimeString);
					else {
						System.out.println("Invalid Time");
						TaskSetCorrect = false;
					}
				}
				else {
					System.out.println("Invalid Time");
					TaskSetCorrect = false;
				}
			}
			
			if(temp[0] == '#') {
				tempWord = CheckDate(temp);
				if(!tempWord.isEmpty()) {
					dd=ConvertDateDD(tempWord);
					mm=ConvertDateMM(tempWord);
					yy=ConvertDateYY(tempWord);
					ddmmyy = tempWord;
				}
				else {
					System.out.println("Invalid Date in CI");
					TaskSetCorrect = false;
				}
			}
			
			if(temp[0] == '$') {
				tempWord = GetWord(temp);
				StoreVenue = tempWord;
			}
			if(temp[0] == ':') {
				tempWord = GetWord(temp);
				StoreLabel = tempWord;
			}
			if(temp[0] == '*') {
				Importance = true;
			}
			if(temp[0]!='*' && temp[0]!='#' && temp[0]!='@' && temp[0]!='$' && temp[0]!='+' && temp[0]!=':') {
				TaskDescription = TaskDescription + item[j]+' ';
			}
		}
		
		//if Date is not set, assume today
		if(ddmmyy.isEmpty() && !DueTimeString.equals("0")) {
			Format formatter;
			Date date = new Date();
		    formatter = new SimpleDateFormat("ddMMyy");
		    String s = formatter.format(date);
		    ddmmyy = s;
		    System.out.println("Date not set, but got time, therefore set as TODAY= " + ddmmyy);
		    dd=ConvertDateDD(ddmmyy);
			mm=ConvertDateMM(ddmmyy);
			yy=ConvertDateYY(ddmmyy);
		}
		else if (!ddmmyy.isEmpty() && DueTimeString.equals("0")){
			System.out.println("Date Set and Time not set, if no other error, add task");
		}
		else
			System.out.println("Date and Time not set, if no other error, set task as forever type");
		
		if(TaskDescription.isEmpty()) {
			System.out.println("no Task des ERROR!");
			TaskSetCorrect = false;
		}
		else {
			StoreTask = TaskDescription;
		}
		
		System.out.println("From CmdInput: TaskSetCorrect");
		if(TaskSetCorrect) {
			return new Task(dd, mm, yy, StartTimeString, DueTimeString, StoreLabel, Importance, StoreTask, StoreVenue);
		
		}
		else {
			output.add("No task modified");
			System.out.println("No task modified");	
		}
		
	 return null; 
	}
	
	/**
	 * @author Dennis
	 * @param time; // (String) "@1700" for 5pm
	 * @return IntTime; // (Integer) 1700 for 5pm
	 */
	public int StartTime(String time) {
		int IntTime=0;
		int k=4;
		char[] charTime;
		
		charTime = time.toCharArray();
		for(int i=1; i<=1000; i*=10) {
			IntTime = IntTime + (charTime[k--]-48)*i;
		}
		return IntTime;
	}
	
	
	/**
	 * @author Dennis
	 * @param time; // (String) "@1700-1800" for 5-6pm
	 * @return IntTime; // (Integer) 1800 for 6pm
	 */
	public int DueTime(String time) {
		int IntTime=0;
		int k=9;
		char[] charTime;
		
		charTime = time.toCharArray();
		for(int i=1; i<=1000; i*=10) {
			IntTime = IntTime + (charTime[k--]-48)*i;
		}
		return IntTime;
	}
	
	
	/**
	 * @author Dennis
	 * @param date //ie, (String) 300512 in ddMMyy for 30th May 2012
	 * @return int //ie, (Integer) 12 for year 2012
	 */
	public int ConvertDateYY(String date) {
		int yy;
		char[] ddmmyy;
		
		ddmmyy = date.toCharArray();
		yy = ((ddmmyy[4]-48)*10) + (ddmmyy[5]-48);

		return yy;
	}
	public int ConvertDateMM(String date) {
		int mm;
		char[] ddmmyy;
		
		ddmmyy = date.toCharArray();
		mm = ((ddmmyy[2]-48)*10) + (ddmmyy[3]-48);
		
		return mm;
	}
	public int ConvertDateDD(String date) {
		int dd;
		char[] ddmmyy;
		
		ddmmyy = date.toCharArray();
		dd = ((ddmmyy[0]-48)*10) + (ddmmyy[1]-48);

		return dd;
	}
	
	public ArrayList<String> upcomingTen() {
		upcomingTenList = basicFeaturesV1.retrieveUpcomingTask(2);
		Task temp = null;
		for(int i=0; i<2; i++) {
			temp = upcomingTenList.get(i);
			guiUpcomingList.add(temp.toString());
		}
	return guiUpcomingList;
	}
	
	/**
	 * @author Dennis
	 * @param temp; //ie, (Array of Characters) #300512 for 30th May 2012
	 * @return tempWord; //ie, (String) "300512"
	 */
	public String CheckDate(char[] temp) { //#020212
		TimeDateValidator timedateValidator = new TimeDateValidator();
		int k=1;
		String tempWord="";
	
		while(k<7) {
			tempWord = tempWord + temp[k];
			k++;
		}
		
		if((temp.length != 7) && !timedateValidator.ValidateDate(tempWord) && (temp.length != 14)) {
			System.out.println("Invalid Date in CD");
			return "";
		}		
		return tempWord;
	}
	
	public String CheckDate2(char[] temp) { //#020212-040212
		TimeDateValidator timedateValidator = new TimeDateValidator();
		int k=8;
		String tempWord="";
	
		while(k<temp.length) {
			tempWord = tempWord + temp[k];
			k++;
		}
		
		if((temp.length != 7) && !timedateValidator.ValidateDate(tempWord) && (temp.length != 14)) {
			System.out.println("Invalid Date in CD2");
			return "";
		}		
		return tempWord;
	}
	
	/**
	 * @author Dennis
	 * @param time; (String) "1700" for 5pm
	 * @return true for Valid time format.
	 */
	public boolean CheckTime(String time) {
		TimeDateValidator timedateValidator = new TimeDateValidator();
		if(timedateValidator.ValidateTime(time))
			return true;
		System.out.println("Invalid Time - CheckTime fn");
		return false;
	}
	/**
	 * @author Dennis
	 * @param temp; //ie, (Array of Characters) $Venue, :Label
	 * @return tempWord; //ie, (String) Venue, Label
	 */
	public String GetWord(char[] temp) {
		int k=1;
		String tempWord="";
		while(k<temp.length) {
			tempWord = tempWord + temp[k];
			k++;
		}
		return tempWord;
	}
	
	public String GetStartTime(char[] temp) {
		int k=1;
		String tempWord="";
		while(k<5) {
			tempWord = tempWord + temp[k];
			k++;
		}
		return tempWord;
	}

	public String GetDueTime(char[] temp) {
		int k=6;
		String tempWord="";
		while(k<temp.length) {
			tempWord = tempWord + temp[k];
			k++;
		}
		return tempWord;
	}
	
	public void RemoveTask(String[] item) {
		int taskIndex = Integer.parseInt(item[1]) - 1;
		if(outputViewList.size() > 0 && taskIndex < outputViewList.size() && taskIndex >= 0) {
			basicFeaturesV1.removeTask(Integer.parseInt(item[1]));
			output.add("Task deleted");
		} else
			output.add("Invalid index");
		
		//System.out.println(outputViewList.size());
		//basicFeaturesV1.printeverything();	
	}
	
	public void DoneTask(String[] item) {
		basicFeaturesV1.copyTask(Integer.parseInt(item[1]));
		basicFeaturesV1.removeTask(Integer.parseInt(item[1]));
		//basicFeaturesV1.printviewlist();	
	}
	
	public void ViewTask(String[] item) {
		char[] temp = item[1].toCharArray();
		String tempStr = "";
		String tempStr2 = "";
		
		//settle error with view command only
		
		
		
		if(item[1].equals("all")) {
			outputViewList = basicFeaturesV1.retrieveUpcomingTask();
			//basicFeaturesV1.printviewlist();
		}
		else if(item[1].equals("impt") || item[1].equals("important") || item[1].equals("*")) {
			//basicFeaturesV1.printviewlist();
			outputViewList = basicFeaturesV1.viewbyImportance();
		}
		else if(temp[0]=='#') {
			if(temp.length==7){
				tempStr = CheckDate(temp); 
				outputViewList = basicFeaturesV1.viewbyDate(Integer.parseInt(tempStr));
				//basicFeaturesV1.printviewlist();
			}
			else if(temp.length==14){
				tempStr = CheckDate(temp); 
				tempStr2 = CheckDate2(temp); 
				//System.out.println(tempStr+"a"+tempStr2);
				outputViewList = basicFeaturesV1.viewbyDatetoDate(Integer.parseInt(tempStr),Integer.parseInt(tempStr2));
				//basicFeaturesV1.printviewlist();
			}
			else 
				output.add("Invalid View by Date input, try #ddmmyy or #ddmmyy-ddmmyy");
		}
		else if(temp[0]==':') {
			outputViewList = basicFeaturesV1.viewbyLabel(item[1]);
			if(outputViewList.isEmpty()) output.add("No task with that label, Note: case sensitive");
			//System.out.println(outputViewList.get(0).venue);
			//basicFeaturesV1.printviewlist();
		}
		else if(item[1].equals("done")) {
			outputViewList = basicFeaturesV1.viewDone();
		}
		else output.add("Invalid View Input");
		
	}
	
	public void ModifyTask(String[] item) {
		int taskIndex = Integer.parseInt(item[1]) - 1;
		//convert input from mod 1 +xxxx into +xxxx only
		int itemSize = item.length - 2;
		String[] newString = new String[itemSize];
		int newStringIterator = 0;
		
		if(outputViewList.size() > 0 && taskIndex < outputViewList.size() && taskIndex >= 0) {
			//Task newTaskTest = new Task(03, 05, 12, "0800", "1000", "", false, "MODIFIED!", "bishanpark");
			
			for(int i=2; i<item.length; i++){
				newString[newStringIterator] = item[i];
				newStringIterator++;
				//System.out.println(newString[newStringIterator]);
			}
			Task newTask = newTask(newString);		
			basicFeaturesV1.modify(Integer.parseInt(item[1]), newTask);
		} else
			output.add("Invalid index");
	}
	
	
	public static void initInput() {
		staticInput = new CommandInput();
	}
	
	
	public void AddTask(Task aTask){
		basicFeaturesV1.addTask(aTask);
	}
	
}